<?php


namespace app\shop\service\chat;


use app\shop\common\consts\RedisKey;
use app\shop\model\chat\GroupUserModel;
use app\shop\model\user\ChatUserModel;
use app\shop\model\user\MessageModel;
use app\shop\model\user\UserModel;
use app\shop\service\until\FileService;
use GatewayClient\Gateway;
use think\facade\Cache;
use think\facade\Log;

class ChatVoiceService
{


    // 发起通话 通话状态:呼叫901，取消902，拒绝903，接听904，未接通905，接通后挂断906，忙线907,其他端操作908
    public function call($chatSign, $userInfo)
    {
        try {
            $chatUserInfo = ChatUserModel::where('chat_sign', $chatSign)->find();
            if (!$chatUserInfo) {
                throw new \Exception('请先发送一次文字消息');
            }
            MessageModel::update(['is_last' => 0], ['chat_sign' => $chatSign]);

            $message = new MessageModel();
            $message->id = generateUuidV4();
            $message->from_user = $userInfo['user_id'];
            $message->from_user_role_id = $userInfo['role_id'];
            $message->content = '语音通话';
            $message->chat_sign = $chatSign;
            $message->type = 'webrtc';
            $message->is_group = 1;
            $message->call_status = 1;
            $message->extends = [
                'event' => 'webrtc',
                'code' => 901,
                'call_time' => time(),
            ];
            $result = $message->save();
            if (!$result) {
                throw new \Exception('拨打失败');
            }
            $msgId = $message->msg_id;

            // 群聊的所有用户
            $userArr = GroupUserModel::where('chat_sign', $chatSign)
                ->where('user_id', '<>', $userInfo['user_id'])
                ->column('user_id');
            $busyUser = [];
            foreach ($userArr as $uid) {
                $info = MessageModel::where('chat_status', '<>', 0)
                    ->whereFindInSet('chat_user', $uid)
                    ->find();
                if ($info) {
                    array_push($busyUser, $uid);
                }
            }

            $chatUserService = new ChatUserService();
            $title = $chatUserService->getGroupTitle($userInfo['role_id'], $chatUserInfo);

            $sendData = [
                'chat_sign' => $chatSign,
                'msg_id' => $msgId,
                'type' => 'calling',
                'call_status' => 1,
                'title' => $title,
                'content' => $message->content,
                'sendTime' => time() * 1000,
                'from_user' => [
                    'user_id' => $userInfo['user_id'],
                    'avatar' => $userInfo['avatar'],
                    'realname' => $userInfo['realname'],
                ],
                'busy_user' => $busyUser,
            ];
            // 推送到群聊
            wsSendMsg($chatSign, 'webrtc', $sendData, 1);
            return $msgId;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    // 接通
    public function accept($msgId, $userInfo)
    {
        try {
            $message = MessageModel::find($msgId);
            if (!$message) {
                throw new \Exception('接听失败！');
            }
            $chatUser = $message['chat_user'];
            if (!$chatUser) {
                $chatUser = $message['from_user'] . ',' . $userInfo['user_id'];
            } else {
                $chatUser = $chatUser . ',' . $userInfo['user_id'];
            }
            $extends = $message['extends'];
            $extends['accept_time'] = time();
            $message->content = '通话中';
            $message->extends = $extends;
            $message->chat_user = $chatUser;
            $message->accept_user = $chatUser;
            $message->call_status = 2;
            $message->save();

            $chatSign = $message['chat_sign'];
            // 推送到群聊
            $chatUserInfo = ChatUserModel::where('chat_sign', $chatSign)->find();
            $chatUserService = new ChatUserService();
            $title = $chatUserService->getGroupTitle($userInfo['role_id'], $chatUserInfo);
            $sendData = [
                'chat_sign' => $chatSign,
                'msg_id' => $msgId,
                'type' => 'accept',
                'call_status' => $message->call_status,
                'title' => $title,
                'content' => $message->content,
                'sendTime' => time() * 1000,
                'from_user' => [
                    'user_id' => $userInfo['user_id'],
                    'avatar' => $userInfo['avatar'],
                    'realname' => $userInfo['realname'],
                ],
            ];
            wsSendMsg($chatSign, 'webrtc', $sendData, 1);
            return true;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    // 拒接
    public function refuse($msgId, $userInfo)
    {
        try {
            $message = MessageModel::find($msgId);
            if (!$message) {
                throw new \Exception('接听失败！');
            }
            $refuseUser = $message['refuse_user'];
            if (!$refuseUser) {
                $refuseUser = $userInfo['user_id'];
            } else {
                $refuseUser = $refuseUser . ',' . $userInfo['user_id'];
            }
            $message->refuse_user = $refuseUser;
            $message->save();

            $chatSign = $message['chat_sign'];
            $allUser = GroupUserModel::where('chat_sign', $chatSign)->column('user_id');
            $refuseUserArr = explode(',', $refuseUser);

            $chatUserInfo = ChatUserModel::where('chat_sign', $chatSign)->find();
            $chatUserService = new ChatUserService();
            $title = $chatUserService->getGroupTitle($userInfo['role_id'], $chatUserInfo);
            if (count($allUser) <= count($refuseUserArr) + 1) {
                // 推送到群聊
                $sendData = [
                    'chat_sign' => $chatSign,
                    'msg_id' => $msgId,
                    'type' => 'refuse_all',
                    'title' => $title,
                    'content' => $message->content,
                    'sendTime' => time() * 1000,
                    'from_user' => [
                        'user_id' => $userInfo['user_id'],
                        'avatar' => $userInfo['avatar'],
                        'realname' => $userInfo['realname'],
                    ],
                ];
                wsSendMsg($chatSign, 'webrtc', $sendData, 1);
            } else {
                // 推送到群聊
                $sendData = [
                    'chat_sign' => $chatSign,
                    'msg_id' => $msgId,
                    'type' => 'refuse',
                    'title' => $title,
                    'content' => $message->content,
                    'sendTime' => time() * 1000,
                    'from_user' => [
                        'user_id' => $userInfo['user_id'],
                        'avatar' => $userInfo['avatar'],
                        'realname' => $userInfo['realname'],
                    ],
                ];
                wsSendMsg($chatSign, 'webrtc', $sendData, 1);
            }
            return true;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    // 挂断
    public function hangup($msgId, $userInfo)
    {
        try {
            $message = MessageModel::find($msgId);
            if (!$message) {
                throw new \Exception('接听失败！');
            }
            $callStatus = $message['call_status'];
            $chatSign = $message['chat_sign'];
            $chatUserInfo = ChatUserModel::where('chat_sign', $chatSign)->find();
            $chatUserService = new ChatUserService();
            $title = $chatUserService->getGroupTitle($userInfo['role_id'], $chatUserInfo);
            if ($callStatus == 1) {
                // 呼叫者自己挂断
                $extends = $message['extends'];
                $extends['cancel_time'] = time();
                $message->content = '通话取消';
                $message->extends = $extends;
                $message->chat_user = '';
                $message->call_status = 4;
                $message->save();

                $chatSign = $message['chat_sign'];
                $this->setLastMessageToRedis($chatSign, $msgId, '通话取消', 'webrtc', $userInfo['user_id']);
                // 推送到群聊
                $sendData = [
                    'chat_sign' => $chatSign,
                    'msg_id' => $msgId,
                    'type' => 'cancel',
                    'call_status' => 4,
                    'title' => $title,
                    'content' => $message->content,
                    'sendTime' => time() * 1000,
                    'from_user' => [
                        'user_id' => $userInfo['user_id'],
                        'avatar' => $userInfo['avatar'],
                        'realname' => $userInfo['realname'],
                    ],
                ];
                wsSendMsg($chatSign, 'webrtc', $sendData, 1);
            } else {
                // 通话结束
                $chatUser = $message['chat_user'];
                $chatUserArr = explode(',', $chatUser);
                $key = array_search($userInfo['user_id'], $chatUserArr);
                if ($key !== false) {
                    unset($chatUserArr[$key]);
                }
                $chatUser = implode(',', $chatUserArr);

                $extends = $message['extends'];

                $acceptTime = $extends['accept_time'];
                $endTime = time();

                $diffTime = $endTime - $acceptTime;
                $minutes = floor($diffTime / 60);
                $seconds = $diffTime % 60;
                $callDuration = sprintf('%d:%d', $minutes, $seconds);
                $extends['call_duration'] = $callDuration;
                $message->extends = $extends;
                $message->chat_user = $chatUser;
                if (count($chatUserArr) <= 1) {
                    $message->call_status = 0;
                    $message->chat_user = '';
                    $message->call_status = 3;
                    $message->content = '通话结束';
                }
                $message->save();

                $chatSign = $message['chat_sign'];
                $this->setLastMessageToRedis($chatSign, $msgId, '语音通话' . $callDuration, 'webrtc', $userInfo['user_id']);
                // 推送到群聊
                $sendData = [
                    'chat_sign' => $chatSign,
                    'msg_id' => $msgId,
                    'type' => 'hangup',
                    'call_status' => $message->call_status,
                    'title' => $title,
                    'content' => $message->content,
                    'sendTime' => time() * 1000,
                    'from_user' => [
                        'user_id' => $userInfo['user_id'],
                        'avatar' => $userInfo['avatar'],
                        'realname' => $userInfo['realname'],
                    ],
                ];
                wsSendMsg($chatSign, 'webrtc', $sendData, 1);

            }
            return true;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * 通话的用户
     * @param $chatSign
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getVideoGroupUser($chatSign)
    {
        $message = MessageModel::where('chat_sign', $chatSign)->where('call_status', 2)->find();
        if (!$message) {
            return ['chat_user' => '', 'msg_id' => 0];
        }
        $chatUser = $message['chat_user'];
        $chatUserArr = explode(',', $chatUser);

        $userList = UserModel::whereIn('user_id', $chatUserArr)->field('user_id,realname,avatar')->select();
        $returnData = [
            'chat_user' => $userList,
            'msg_id' => $message['msg_id'],
        ];
        return $returnData;
    }

    /**
     * 设置最后一条消息到redis
     * @param $chatSign
     * @param $msgId
     * @param $content
     * @param $msgType
     * @param int $fromUid
     * @param string $fromUserName
     * @param int $isUndo
     */
    public function setLastMessageToRedis($chatSign, $msgId, $content, $msgType, $fromUid, $fromUserName = '', $isUndo = 0)
    {
        $redisKey = sprintf(RedisKey::LAST_MESSAGE, $chatSign);
        $redisHandler = Cache::store('redis')->handler();
        $redisHandler->HMSET($redisKey, [
            'msg_id' => $msgId,
            'last_content' => $content,
            'type' => $msgType,
            'last_send_time' => time() * 1000,
            'from_uid' => $fromUid,
            'from_user_name' => $fromUserName,
            'is_undo' => $isUndo,
        ]);
        $redisHandler->expire($redisKey, 86400 * 20);
    }
}